package com.xyzk.diagnose.tools;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.util.Arrays;

import com.xyzk.diagnose.tools.ReadThread.ReadCallback;

import android.text.TextUtils;
import android.util.Log;
//单例模式

public class JCommunication
{
	private static final String TAG = "JCommunication";
	private static  JCommunication mJcom;
	//String m_SerialPortname = "/dev/ttyMSM1"; //q15P
	String m_SerialPortname = "/dev/ttyHSL2"; //Q15
	//String m_SerialPortname = "/dev/ttyUSB0"; //86W
	int mbaud = 921600;
	public boolean exit;
	public LogFile m_log = null;

	private SerialPort   mSerialPort = null;
	private OutputStream mOutputStream = null;
	private InputStream  mInputStream = null;
	private ReadThread   mReadThread = null;
	private static int mRead = 0;
	private static byte [] Readbuf= new byte[1024];

	private JCommunication(){
		exit = false;
		m_log = LogFile.getInstance();

		boolean isok = OpenUart();
		if(m_log != null)
			m_log.PrintAppend(0,"Open Port:" + (isok == true?"OK":"NG"));
	}
	public String getFilePaths(){
		return m_log.getFilePath();
	}

	public synchronized static JCommunication getInstance(){
		return mJcom == null ? mJcom = new JCommunication() : mJcom;
	}
	void exit()
	{
		if(Common.DEBUG) Log.e(TAG,"执行了exit");
		Close();
		exit = true;
	}
	public boolean SetStandCanAutoFrame(int Pid,byte [] Pbuf,int Plen)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x0D,0x10,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		cmd[8] = (byte) (Pid / 0x100);
		cmd[9] = (byte) (Pid &0xFF);
		for(int i = 0; i < Plen; i ++)
		{
			cmd[10 + i] = Pbuf[i];
		}
		//¼ÆËãÐ£Ñé
		cmd[10 + Plen] = Commonfunc.calcuCheckCode(cmd, 4, 10 + Plen);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
		{
			if(m_log != null) m_log.printMessage(0,"SetAutoCmd:" + Pid + ":" + Commonfunc.bytesToHexString(Pbuf, 0, Plen));
			return true;
		}
		else
			return false;
	}

	//毫秒
	private void Sleep(int times)
	{
		try {
			Thread.sleep(times, 0);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//*********************************API**************************************************
	//CAN只发一帧数据,返回1成功
	public int CanSendOneOnly(int SendId,byte[] send,int Plen)
	{
		byte [] cmd = new byte[]{0x11,0x39};
		byte [] data = new byte[128];
		data[0] = 0x01;  //can模式
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = (byte) (SendId / 0x100);
		data[4] = (byte) (SendId % 0x100);
		//添加发送命令的帧数以及帧内容 g
		System.arraycopy(send, 0, data, 5, Plen);
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, 13, Sendbuf);
		//发送
		byte [] readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, readbuf, readbuf.length, Common.SET_MAX_TIME);
		if(iRet == 9) //只收到发送成功数据
		{
			iRet = 1;
		}
		else
			iRet = 0;
		if(m_log != null)
			m_log.PrintAppend(SendId,Commonfunc.bytesToHexString(send, 0, Plen));
		return iRet;
	}

	public int CanSendAndRecvO2O_Spec(int Psid,int Prid,byte [] Send,int Plen,byte [] Recv,int Psize,int errorcode,int maxtime)
	{
		int error = 0;
		byte [] Readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.cmd_freq; i ++)
		{
			iRet = CanSendOne2One(Psid,Prid,Send,Plen,Readbuf,Readbuf.length,maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Sleep(Common.waittime);
		}
		if(i >= Common.cmd_freq) return 5001; //无响应
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		System.arraycopy(Readbuf, 0, Recv, 0, iRet);
		return error;
	}
	private int CanSendOne2One(int Psid,int Prid,byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x32};
		byte [] data = new byte[128];
		//记录发送的数据
		if(m_log != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			m_log.PrintAppend(Psid,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		//send id
		data[2] = (byte) ((Psid >>> 8) & 0xFF);
		data[3] = (byte) (Psid &0xFF);
		//recv id
		data[4] = (byte) ((Prid >>> 8) & 0xFF);
		data[5] = (byte) (Prid &0xFF);
		//特征报文
		data[6] = 0x00;
		data[7] = 0x01;
		data[8] = (byte) 0xFF;
		//data 8bytes
		System.arraycopy(send, 0, data, 9, Plen);

		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, 17, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOneNew(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.CMD_MAX_TIME);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1) //单帧
						{
							iRet = 8;
							for(int i = 0;i < 8; i ++)
								recv[i] = Readbuf[10 + i];
						}
						else if (Readbuf[8] > 1) //多帧
						{
						}

					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (Readbuf[17] == 1) //单帧
				{
					iRet = 8;
					for(int i = 0;i < 8; i ++)
						recv[i] = Readbuf[19 + i];
				}
				else if (Readbuf[17] > 1) //多帧
				{
				}
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(m_log != null && iRet > 0){
			m_log.PrintAppend(Prid,Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}
	public int CanOne2OneUDS(int Preq,int Pres,byte [] Send,int Plen,byte [] Recv,int Perror,int Pmaxtime,int Pfreq)
	{
		int error = 0;
		int i;
		for(i = 0; i < Pfreq; i ++)
		{
			error = CanOne2OneUDS(Preq,Pres,Send,Plen,Recv,Pmaxtime);
			if(error > 0) break;
			else if(error < 0)
			{
				error = 5002;
			}
			if(exit) return 5002;
			Sleep(Common.WAIT_TIME);
		}
		if(i >= Pfreq)
			error = 5001; //无响应
		return error;
	}
	//-1 -- 断网; -2 -- 超时; -3 -- IO异常; -4 -- 校验失败; -5 -- box异常
	private int CanOne2OneUDS(int Preq,int Pres,byte[] send,int Plen,byte [] recv,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x30};
		int framenum = 0;
		if(Plen > 20)
		{
			Sleep(1);
		}
		if(Plen <= 8)
		{
			framenum = 1;
		}
		else if(Plen <= 0x100)
		{
			framenum = (Plen + 6) / 7;
		}
		else
			framenum = (Plen + 5) / 7;
		byte [] data = new byte[10 + framenum * 8];
		Arrays.fill(data, (byte) 0);
		//记录发送的数据
		if(m_log != null)
			m_log.PrintAppend(Preq,Commonfunc.bytesToHexString(send, 0, Plen));
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//send id
		data[2] = (byte) (Preq / 0x100);
		data[3] = (byte) (Preq % 0x100);
		//recv id
		data[4] = (byte) (Pres / 0x100);
		data[5] = (byte) (Pres % 0x100);
		//特征报文
		data[6] = 0;
		data[7] = 0;
		//添加发送命令的帧数以及帧内容
		data[8] = (byte) (framenum / 0x100);
		data[9] = (byte) (framenum % 0x100);
		//添加内容
		int k = 0;
		if(Plen <= 0x100) //1位长度
		{
			if(Plen <= 8)
			{
				System.arraycopy(send, 0, data, 10, Plen);
			}
			else
			{
				//第一帧
				data[10] = 0x10;
				System.arraycopy(send, 0, data, 11, 7);
				for(k = 1; k < framenum - 1; k ++)
				{
					data[10 + k * 8] = (byte) (0x20 + k % 0x10);
					System.arraycopy(send, k * 7, data, 11 + k * 8, 7);
				}
				//last
				k = (framenum - 1);
				data[10 + k * 8] = (byte) (0x20 + k % 0x10);
				int v_lastlen = Plen % 7;
				if(v_lastlen == 0)
					v_lastlen = 7;
				System.arraycopy(send, k * 7, data, 11 + k * 8, v_lastlen);
			}
		}
		else
		{
			//第一帧
			data[10] = (byte) (0x10 + send[0]);
			System.arraycopy(send, 1, data, 11, 7);
			for(k = 1; k < framenum - 1; k ++)
			{
				data[10 + k * 8] = (byte) (0x20 + k % 0x10);
				System.arraycopy(send, 1 + k * 7, data, 11 + k * 8, 7);
			}
			//last
			k = (framenum - 1);
			data[10 + k * 8] = (byte) (0x20 + k % 0x10);
			int v_lastlen = (Plen - 1) % 7;
			if(v_lastlen == 0)
				v_lastlen = 7;
			System.arraycopy(send, 1 + k * 7, data, 11 + k * 8, v_lastlen);
		}

		//组合成命令
		byte [] Sendbuf = new byte [9 + data.length];
		int Sendlen = addData2Cmd(cmd, data, data.length, Sendbuf);

		//发送
		byte [] Readbuf = new byte[512];
		int iRet =SendOneToOneNew(Sendbuf, Sendlen, Readbuf, Readbuf.length, maxtime);
		if(iRet != 9) //nok
		{
			if(iRet >= 0) //
				iRet = -5;
			return iRet;
		}
		//if(m_log != null)
		//	m_log.PrintAppend(Preq,"ok");
		//接收后面数据
		while(true)
		{
			iRet = ReaddataComplete(Readbuf, Readbuf.length, maxtime + 100);
			if(iRet > 9) //ok
			{
				if((Readbuf[5] == 0x0D) && (Readbuf[10] == 0x03) && (Readbuf[11] == 0x7F) && (Readbuf[13] == 0x78)) //wait
				{
					if(m_log != null){
						m_log.PrintAppend(Pres,Commonfunc.bytesToHexString(Readbuf, 10, 14));
					}
					if(maxtime < 5000)
						maxtime = 5000;
					Sleep(10);
					continue;
				}
				else //拷贝数据
				{
					//拆开CAN包重组CAN数据
					if((Readbuf[8]&0xFF) > 20) break;
					if (Readbuf[8] == 1) //单帧
					{
						iRet = Readbuf[10] + 1;
						for(int i = 0;i < iRet; i ++)
							recv[i] = Readbuf[10 + i];
					}
					else if (Readbuf[8] > 1) //多帧
					{
						iRet = ((Readbuf[10]&0x0F) << 8) + (Readbuf[11]&0xFF) + 1;
						for(int i = 0; i < Readbuf[8]; i ++)
						{
							System.arraycopy(Readbuf,9 + i * 9 + 2, recv, i * 7, 7);
						}
					}
					break;
				}
			}
			else if(iRet == 9 && Readbuf[6] == 0x6F && Readbuf[7] == 0x02) //timeout
			{
				iRet = -2; break;
			}
			else
				break;
		}

		//记录接收的数据
		if(m_log != null){
			if(iRet > 0)
				m_log.PrintAppend(Pres,Commonfunc.bytesToHexString(recv, 0, iRet));
			else
			{
				if(iRet == -1)
					m_log.PrintAppend(0, "Connect Lost!");
				else if(iRet == -2)
				{
					m_log.PrintAppend(0, "Time out!");
					iRet = 0;
				}
				else if(iRet == -3)
					m_log.PrintAppend(0, "IOException!");
				else  if(iRet == -4)
				{
					m_log.PrintAppend(0, "Check failed!");
					iRet = 0;
				}
				else  if(iRet == -5)
					m_log.PrintAppend(0, "Box error!");
				else
					m_log.PrintAppend(0, "Else error!");
			}
		}
		return iRet;
	}
	//*********************************************************************************************
	private int addData2Cmd(byte [] cmd,byte [] Pdata,int Plen,byte [] Pcmdbuf)
	{
		int cmdlen = 0;
		//这里组成发送的命令
		//先添加发送帧头
		Pcmdbuf[0] = 0x55;
		Pcmdbuf[1] = (byte) 0xAA;
		Pcmdbuf[2] = (byte) 0xC1;
		Pcmdbuf[3] = (byte) 0xB1;
		//计算长度
		cmdlen = 4 + 2 + 2 + Plen + 1;
		//填入长度字节
		Pcmdbuf[4] = (byte) ((cmdlen - 6) / 0x100);
		Pcmdbuf[5] = (byte) ((cmdlen - 6) % 0x100);
		//填入命令字
		Pcmdbuf[6] = cmd[0];
		Pcmdbuf[7] = cmd[1];
		//填入DATA
		for(int i = 0; i < Plen; i ++)
		{
			Pcmdbuf[8+i] = Pdata[i];
		}
		//计算校验
		Pcmdbuf[cmdlen - 1] = Commonfunc.calcuCheckCode(Pcmdbuf,4,cmdlen - 1);
		return cmdlen;
	}
	//只取9byte
	private int ReaddataAuto(byte[] Precv,int Psize,int maxtime)
	{
		int readlen = 0;
		int datalen = 0;
		if(mOutputStream == null || mOutputStream == null)
		{
			if(Common.DEBUG) Log.e(TAG,"Readdata exit 1");
			return -1; //断线
		}
		long starttime = System.currentTimeMillis(); //获得起始时间
		long endtime = starttime;
		while(true)
		{
			Sleep(1);
			if(mOutputStream == null || mInputStream == null  || exit == true)
			{
				break; //未连接
			}
			//readlen = mInputStream.read(Precv);
			//len = mInputStream.read(vbuf);
			if(mRead >= 9)
			{
				readlen = 9;
				System.arraycopy(Readbuf, 0, Precv, 0, readlen);
				mRead -= readlen;
				if(mRead > 0)
					System.arraycopy(Readbuf, 9, Readbuf, 0, mRead);
			}
			if(readlen  == 9)
			{
				if(((Precv[0]&0xFF) == 0x55) && ((Precv[1]&0xFF) == 0xAA))  //得到头
				{
					datalen = ((Precv[4]&0xFF) << 8) + (Precv[5]&0xFF);
					if(datalen == (readlen - 6)) //有完整数据,取数据返回
					{
						break;
					}
				}
			}
			Sleep(1);
			endtime = System.currentTimeMillis();
			if(endtime  > (starttime + maxtime)) //超时
			{
				if(Common.DEBUG) Log.i(TAG,"超时退出!");
				readlen = -2; //超时
				break;
			}
		}
		return readlen;
	}

	private int ReaddataComplete(byte[] Precv,int Psize,int maxtime)
	{
		int readlen = 0;
		int datalen = 0;
		//byte [] readbuf = new byte[256];
		if(mOutputStream == null || mOutputStream == null)
		{
			if(Common.DEBUG) Log.e(TAG,"Readdata exit 1");
			return -1; //断线
		}
		long starttime = System.currentTimeMillis(); //获得起始时间
		long endtime = starttime;
		while(true)
		{
			Sleep(1);
			if(mOutputStream == null || mInputStream == null  || exit == true)
			{
				break; //未连接
			}

			if(mRead > 8)
			{
				if(((Readbuf[0]&0xFF) == 0x55) && ((Readbuf[1]&0xFF) == 0xAA))  //得到头
				{
					datalen = ((Readbuf[4]&0xFF) << 8) + (Readbuf[5]&0xFF);
					readlen = datalen + 6;
					if(datalen <= (mRead - 6)) //有完整数据,取数据返回
					{
						System.arraycopy(Readbuf, 0, Precv, 0, readlen);
						//偏移
						if(mRead > readlen)
							System.arraycopy(Readbuf, readlen, Readbuf, 0, mRead - readlen);
						break;
					}

				}
			}
			Sleep(2);
			endtime = System.currentTimeMillis();
			if(endtime  > (starttime + maxtime)) //超时
			{
				if(Common.DEBUG) Log.i(TAG,"超时退出!");
				readlen = -2; //超时
				break;
			}
			//if(m_log != null)
			//	m_log.PrintAppend(0,"readlen =" + readlen + ";Start=" + starttime + ";end=" + endtime + ";maxtime=" + maxtime);
		}
		return readlen;
	}
	//只收数据,保证收到完整帧
	private int Readdata(byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		int all_len = 0;
		byte [] readbuf = new byte[256];
		if(mOutputStream == null || mInputStream == null)
		{
			if(Common.DEBUG) Log.e(TAG,"Readdata exit 1");
			return -1; //未连接
		}
		long starttime = System.currentTimeMillis(); //获得起始时间
		long endtime = starttime;
		while(true)
		{
			Sleep(1);
			if(mOutputStream == null || mInputStream == null  || exit == true)
			{
				if(Common.DEBUG) Log.e(TAG,"Readdata exit 2" + "dout=" + mOutputStream + ";din=" + mInputStream + ";exit=" + exit);
				break; //未连接
			}
			len = mRead;
			if(len > 0)
			{
				System.arraycopy(Readbuf, 0, readbuf, all_len, len);
				mRead = 0;
				all_len += len;
			}
			if((all_len == 9) && (readbuf[5] == 0x03)) //收到下位机回复
			{
				//if(Common.Debug) Log.e(TAG,"Readdata exit 3");
				break;
			}
			else if(all_len > 9) //收到超过一帧,或者长帧
			{
				if(readbuf[5] == 0x03) //表示是多帧
				{
					if((all_len - 9) == ((readbuf[14] & 0xFF) + 6))
					{
						//if(Common.Debug) Log.e(TAG,"Readdata exit 4");
						break;
					}
				}
				else	//长帧
				{
					if(all_len == ((readbuf[5] & 0xFF) + 6))
					{
						//if(Common.Debug) Log.e(TAG,"Readdata exit 5");
						break;
					}
				}
			}
			endtime = System.currentTimeMillis();
			if((endtime  - starttime) >  maxtime) //超时
			{
				if(Common.DEBUG) Log.i(TAG,"超时退出!");
				break;
			}
		}
		if(all_len < Psize)
			System.arraycopy(readbuf, 0, Precv, 0, all_len);
		return all_len;
	}
	//发送数据，发一次收一次
	private int SendOneToOne(byte[] Psend,int Plen,byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		if(mOutputStream == null || mInputStream == null) return -1; //未连接
		mRead = 0;
		try {
			//if(mInputStream.available() > 0)  //先清除数据
			//	mInputStream.read(Precv, 0, mInputStream.available());
			//Sleep(1);
			mOutputStream.write(Psend, 0, Plen);
			//Sleep(1);
			mOutputStream.flush();
			//Sleep(1);
			if(Common.DEBUG) Log.i(TAG,"Send:" + Commonfunc.bytesToHexString(Psend, 0,Plen));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(Common.DEBUG) Log.e(TAG,"Send异常");
		}
		len = Readdata(Precv,Psize,maxtime);
		return len;
	}
	//发送数据，发一次收一次
	private int SendOneToOneNew(byte[] Psend,int Plen,byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		byte [] v_Ans = new byte[256];
		if(mOutputStream == null || mInputStream == null) return -1; //未连接
		mRead = 0;
		try {
			mOutputStream.write(Psend, 0, Plen);
			mOutputStream.flush();
			Sleep(2);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			//if(Common.Debug) Log.e(TAG,"Send异常");
		}
		len = ReaddataAuto(v_Ans,v_Ans.length,Common.SET_MAX_TIME);
		return len;
	}
	//Readversion
	public String  ReadVersion()
	{
		String readver = "N.ok";
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x03,0x20,0x08,0x00};
		byte [] Ans = new byte[128];
		//计算校验
		cmd[8] = Commonfunc.calcuCheckCode(cmd, 4, 8);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
		{
			//解析数据12位序列号+Boot版本+app版本+下载状态
			byte [] serial = new byte[12];
			System.arraycopy(Ans, 8, serial, 0, 12);
			readver = new String(serial) + "_Boot:" + (Ans[20]&0xFF) + "." + Commonfunc.byteToString(Ans[21]);
			readver +=  "_App:" +  (Ans[22]&0xFF) + "." + Commonfunc.byteToString(Ans[23]);
		}
		if(m_log != null)
			m_log.PrintAppend(0,"ReadVersion:" +readver );
		return readver;
	}
	//设置CAN线波特率
	public boolean SetCanBaud(long baud)
	{
		boolean isok = false;
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x06,0x10,0x03,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		//获取波特率
		cmd[8] = (byte) ((baud / 0x10000) & 0xFF);
		cmd[9] = (byte) ((baud / 0x100) & 0xFF);
		cmd[10] = (byte) (baud & 0xFF);
		//计算校验
		cmd[11] = Commonfunc.calcuCheckCode(cmd, 4, 11);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			isok = true;
		if(m_log != null)
			m_log.PrintAppend(0,"SetBaud:" + baud + " " + (isok == true?"OK":"Failed"));
		return isok;
	}
	//设置P-CAN或B-CAN
	public boolean SetCanMode(int mode)
	{
		boolean isok = false;
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x04,0x10,0x09,0x00,0x00};
		byte [] Ans = new byte[128];
		cmd[8] = (byte) (mode & 0xFF);
		//计算校验
		cmd[9] = Commonfunc.calcuCheckCode(cmd, 4, 9);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			isok =  true;
		//记录设置CAN
		if(m_log != null)
			m_log.PrintAppend(0,"SetCan:" + mode + " " + (isok == true?"OK":"Failed"));
		return isok;
	}
	//设置can过滤
	public boolean SetCanFilter(byte [] Pbuf,int num)
	{
		boolean isok = false;
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x08,0x10,0x04,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		cmd[8] = (byte) (num & 0xFF);
		for(int i = 0; i < num * 2; i ++)
		{
			cmd[9 + i] = Pbuf[i];
		}
		//计算校验
		cmd[9 + num*2] = Commonfunc.calcuCheckCode(cmd, 4, 9 + num * 2);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			isok =  true;
		//记录设置CAN ID
		if(m_log != null)
		{
			m_log.PrintAppend(0,"SetCanID:" + Commonfunc.bytesToHexString(Pbuf, 0, num * 2) + " " + (isok == true?"OK":"Failed"));
		}
		return isok;
	}
	//设置can流控帧
	public boolean SetCanAutoFrame(byte [] Pbuf,int Plen)
	{
		boolean isok = false;
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x0B,0x10,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		for(int i = 0; i < Plen; i ++)
		{
			cmd[8 + i] = Pbuf[i];
		}
		//计算校验
		cmd[8 + Plen] = Commonfunc.calcuCheckCode(cmd, 4, 8 + Plen);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			isok = true;
		if(m_log != null)
			m_log.PrintAppend(0,"SetCAN control frame:" + Commonfunc.bytesToHexString(Pbuf, 0, Plen) + " " + (isok == true?"OK":"Failed"));
		return isok;
	}
	//设置时序
	public boolean SetCommunTimer(int P1,int P2,int P3,int P4)
	{
		boolean isok = false;
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x09,0x10,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		cmd[8] = (byte) (P1 & 0xFF);
		cmd[9] = (byte) ((P2 / 0x100) & 0xFF);
		cmd[10] = (byte) (P2 & 0xFF);
		cmd[11] = (byte) ((P3 / 0x100) & 0xFF);
		cmd[12] = (byte) (P3 & 0xFF);
		cmd[13] = (byte) (P4 & 0xFF);
		//计算校验
		cmd[14] = Commonfunc.calcuCheckCode(cmd, 4, 14);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			isok =  true;
		if(m_log != null)
			m_log.PrintAppend(0,"Set Time P1-P4:" + P1 + "," + P2 + "," + P3 + "," + P4 + " " + (isok == true?"OK":"Failed"));
		return isok;
	}
	public void saveLogData(int path,String data){
		if(m_log != null) m_log.printMessage(path,data);
	}
	public void PrintLog(String Pstr)
	{
		if(m_log != null)
		{
			m_log.PrintLog(Pstr);
		}
	}
	public void OpenLogfile(String Pfile)
	{
		m_log = new LogFile(Pfile, true);
	}
	public long GetLogfileSize()
	{
		return m_log.getFileSize();
	}
	public String GetLogfileName()
	{
		//去掉LOG标志
		int v_adr = m_log.m_filename.indexOf("LOG");
		String v_name = null;
		if(v_adr > 0 && v_adr < 100)
			v_name = m_log.m_filename.substring(v_adr + 4);
		else
		{
			v_name = Commonfunc.getDate("") + "/" + m_log.m_filename;
		}
		return v_name;
	}
	public long readLogfile(char [] Pbuf)
	{
		return m_log.readFile(Pbuf);
	}

	private boolean OpenUart()
	{
		boolean isok = false;
		Log.d("getSerialPort", "serialDev = "+ m_SerialPortname +";  part_baud = " + mbaud);
		try {
			if(!TextUtils.isEmpty(m_SerialPortname)){
				mSerialPort  =  new SerialPort(new File(m_SerialPortname), mbaud, 0);

				if( mSerialPort != null ){

					mOutputStream = mSerialPort.getOutputStream();
					mInputStream  = mSerialPort.getInputStream();

					mReadThread = new ReadThread(mInputStream);
					mReadThread.setCallBack(new ReadCallback() {

						@Override
						public void onReceivedData(final byte[] data ,final int size) {

							Log.v(TAG, "onReceivedData: size= " + size);
							//if(m_log != null)
							// m_log.PrintLog(Commonfunc.bytesToHexStringP(data, 0, size));
							if((mRead + size) < 1024)
								System.arraycopy(data, 0, Readbuf, mRead, size);
							mRead += size;
						}
					});
					mReadThread.start();
					isok = true;
				}else{
					return isok;
				}
			}
		} catch (InvalidParameterException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return isok;
	}
	private void Close()
	{
		try{
			if(mInputStream != null){
				mInputStream.close();
				mInputStream = null;
			}
			if(mOutputStream != null){
				mOutputStream.close();
				mOutputStream = null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		if(mSerialPort != null)
			mSerialPort.CloseUart();;
	}

}
